Introduction
Imagine how strange would it be to
drive a car that can move only
straight forward, without steering
wheel to turn it either left or right.
Strange would also be to have a phone
that can connect only to one phone.
And what about a TV you can't change
channel on ?
We're lucky to only read about these
funny cases where the lack of choice
could lead to a not very happy end.
While computer software likes happy
ends, it contains variety of
functions, and some of them deal with
flow control. Giving ability of
choice, programmers make software
interactive. Meaning, user is not
watching a movie, but participating in
interactive sessions between software
and it's user.
The car will take you almost wherever
you want, thanks to the steering
wheel. To make MMB application go at
desired path, you'll use steering
wheel too - flow control functions
!
MMB uses two ways of controlling
script flow: If statements and
For..Next loops.
If statements
Introduction
Making decisions is what if statements
are all about. By reading road signs
you'll adjust the speed or direction
of your vehicle. Hitting the ball in
the right direction will make a goal
for your team. Adding extra pepper
will make your meal spicey.
As you can see from the image above,
depending on what you put on the house
of playing cards - that house will
either keep standing or
collapse.
MMB uses variable label as platform
for variable value (object you put on
the platform).
Basic If statement syntax
Script code lines consist of:
a) writing If clause:
If
b) opening parenthesis with variable
label:
(object$
c) followed by equal sign:
=
d) then writing contents (value) of
variable at the end, behind label and
equal sign, followed by closing
parenthesis:
'rock')
e) and adding of then clause at the
end of the first line:
Then
Put together, first line of if
statement will look like
this:
If (object$='rock')
Then
This line instructs MMB to perform
certain actions if content of string
variable object$ matches
exactly the string specified inside
single quotes (in this case:
rock).
And what if variable really matches
specified content ? After the line
above, you will continue writing
script lines that will be executed in
the case of content match:
MyText$='Object put to platform is:
'+object$
Message("","MyText$")
When you're done writing code lines
that should be performed in match
case, you can use another
clause:
Else
...and continue writing lines that
should be performed if variable
doesn't match specified content. For
example:
MyText$='Unknown object has been put
to platform'
Message("","MyText$")
Adding of else clause and script lines
of else case are optional. But,
whatever you decide, you must tell MMB
when you're done with if statement, by
adding the end clause:
End
Let's see now how entire if
statement code looks like !
If (object$='rock') Then
MyText$='Object put
to platform is: '+object$
Message("","MyText$")
Else
MyText$='Unknown object has been put
to platform'
Message("","MyText$")
End
Translated: if content of string
variable object$ is the rock,
text assigned to MyText$ string
variable will be "Object put to
platform is: rock" and it'll be
displayed in MMB's message box.
But if content of string variable
object$ is something else, text
assigned to MyText$ string
variable will be "Unknown object has
been put to platform" and it'll be
displayed in MMB's message box. All
lines put after Else clause
will be executed only when If
clause is false.
Of course, you don't have to use
Else if you don't want
to:
If (object$='rock') Then
MyText$='House of
cards has collapsed !'
Message("","MyText$")
Return()
End
These code lines will display message
box with text "House of cards has
collapsed !" if object$
variable contents is rock , and
after that it'll call Return() command
to stop going any further in script
code lines (both in & out of if
statement code lines).
Multiple If statements
Another option is to use multiple
If statements, to make more
decisions:
If (TankVolume=10) Then
Message("
Please add some more
fuel
","")
Return()
End
If (TankVolume=50) Then
Message("
Tank is half
full
","")
Return()
End
If (TankVolume=100) Then
Message("
Tank is full
!
","")
Else
Message("Tank
status unknown","")
End
The first thing you'll notice above
is - we're using numerical variables.
The principle is completely the same
as for string variables. Here we take
numerical variable TankVolume
that contains some value. Once it goes
through multiple if statements, we'll
have message box pop up even when
neither of if cases is true,
because last if statement also
includes Else clause,
containing the code that will be
executed if code lines didn't go in
any other direction.
Using value range in If
statements
It wouldn't be very handy to have
only fixed values in if
statements:
We would need too many if cases to
handle all sub-values. This looks
better:
So, not only equal operator is
available, but variety of others:
Operator
|
Name
|
=
|
equals
|
<>
|
different
than
|
<
|
less than
|
>
|
greater than
|
<=
|
less than or
equal
|
=>
|
more than or
equal
|
Put into code lines, here's how these
operators look like:
If (Volume<10) Then
Message("Volume is less than 10
!","")
End
(displays message box if content of
numerical variable Volume is under
10)
If (Volume<=49) Then
Message("Volume is under
50.","")
End
(displays message box if content of
numerical variable is 49 or under that
number)
If (Volume<>100) Then
Message("Volume is not
100.","")
End
(displays message box if content of
numerical variable is different than
100)
Multiple cases in If
statements
Another neat feature of if statements
in MMB is ability to use more
conditions in one line.
There are two available
operators:
To use these, you'll start by writing
an If clause:
If
...opening parenthesis with first
variable label:
(OldUser$
...followed by equal sign:
=
...then writing content (value) of
variable at the end, behind label and
equal sign:
'John'
...and adding either & or
| operator:
&
After writing this, you'll start
adding the next case, without opening
new parenthesis, but continuing
writing variable name inside current
one:
NewUser$
...followed by equal sign:
=
...and writing contents (value) of
variable at the end, behind label and
equal sign:
'Peter'
Now you can either continue adding
another case, or finish the if
statement code line by closing
parenthesis:
)
... and adding Then clause at
the end of the first line:
Then
Put together, first line of If
statement with more conditions
looks like this:
If (OldUser$='John' &
NewUser$='Peter')
Then
And what will this code line do ?
Check value of OldUser$ for a
match with name John. If the
match exists, it'll go and check if
value of NewUser$ matches name
Peter. If that's the case, MMB
will perform code lines entered after
Then clause.
Here's an example with | (or)
operator:
If (OldUser$='John' |
NewUser$='Peter')
Then
Case will be positive if either
OldUser$ or NewUser$ matches the case,
and MMB will perform code lines
entered after Then clause. If
neither match, if statement code lines
are ignored.
And there are even more combinations
here ! Variables can be compared with
other variables, multiple cases can be
combined between numerical and string
variables, using of <> operator
is available not only for numerical,
but also for string variables. Nested
if statements (one in another) are
also available here.
Let's see how these features work,
one by one...
Variable vs. Variable
In many occasions, values are stored
in variables. It's possible to compare
two variables in the if statements and
check do they match:
If (User1$=User2$) Then
Message("Users are identical
!","")
End
Example above compares 2 string
variables (User1$, User2$) and if they
match, message box is displayed,
saying "Users are identical !". Here's
one example that uses numerical
variables:
If (CurrentLevel>Recommended)
Then
Message("Level is higher than
recommended
!","")
End
Example checks if value of numerical
variable CurrentLevel is higher than
value of numerical variable
Recommended. If it is, message
box is displayed, saying "Level is
higher than recommended !"
If statements with mixed
variables
Another advantage of if statements
with multiple cases is ability to look
for matches on both string and
numerical variables inside the same if
statement. Here's an example:
If (UserName$='Bundy' &
UserHeight>197) Then
Message("Bundy is higher than 197
cm","")
End
Code above checks match on 2
variables - string variable
UserName$ and numerical
variable UserHeight. If string
variable contains name Bundy, and if
numerical variable content is higher
than 197, message box will display:
"Bundy is higher than 197 cm".
Checking match with
<>
In some cases you won't be interested
in checking value range or match, but
only see if either numerical or string
variable differs from specified value.
One of usual examples is checking of
passwords, where your program only
wants to know if user input matches
(either variable or fixed) password.
So let's see how this works:
If
(UserInput$<>'SoftwareRegKey')
Then
Message("Entered software reg key is
not valid !","")
End
You remember <> operator from
previous paragraphs - and it's by
default used for numerical variables.
But in MMB you can use <> to
search for a difference on string
variables too.
Just for the record, here's an
example with numerical
variable:
If (MyHeight<>YourHeight)
Then
Message("We have different height
!","")
End
Here we check the difference between
two numerical variables. If difference
exists, message box is displayed,
saying: "We have different height
!".
Nested If statements
In addition to multiple if statements,
here's another feature that is
actually longer version of multiple
case if statement. It's possible to
enter second if statement inside of
the first one and have parts of the
code executed depending on case
match.
If (UserName$='Bundy') Then
If
(UserHeight>197) Then
Message("Bundy is higher than 197
cm","")
End
End
Although you could replace this
example with shorter version:
If (UserName$='Bundy' &
UserHeight>197) Then
Message("Bundy is higher than 197
cm","")
End
...by using nested If statements it's
possible to execute some other code
inside of the first statement, that
doesn't depend on the second if
statement match case:
If (UserName$='Bundy') Then
Message("Hello Bundy
!","")
If
(UserHeight>197) Then
Message("Bundy is higher than 197
cm","")
End
End
Code lines above will check if string
variable UserName$ matches name
"Bundy". If it does, message box with
"Hello Bundy !" text is displayed.
After that, second (nested) if
statement is checked with numerical
variable UserHeight. If number is
higher than 197, second message box
will be displayed, saying: "Bundy is
higher than 197 cm".
So, even if Bundy is not higher than
197 cm, first (Hello Bundy !) message
box will be displayed. The same
principle goes for code lines entered
below entire second if
statement.
Notice where nested if statements are
entered - End clause of
previous if statement is not put above
'em, but below, encapsulating nested
statements. You can add as many nested
statements as you like and brake
further execution with Return()
command:
If
(UserName$='Bundy')
Then
Message("Hello Bundy
!","")
If (UserHeight>197)
Then
Message("Bundy is higher than 197
cm","")
If (UserWeight>110)
Then
Message("Bundy weighs more than 110
kilos","")
Return()
End
Message("Bundy weighs less than/or 110
kilos","")
End
End
If statements are marked with
different colors so you can see which
End clause belongs to which
statement. First message box is
displayed if UserName$ matches
name "Bundy". Second message box is
displayed if numerical variable
UserHeight contains number
higher than 197. Now, third if
statement (marked red) is interesting
- if numerical variable
UserWeight is higher than 110,
message box will display "Bundy weighs
more than 100 kilos" and that's where
execution of all if statements is
stopped with Return() . But if
UserWeight is not greater than
110, message box will display "Bundy
weighs less than/or 110 kilos".
For..Next loops
Introduction
Keep walking.
Could you repeat that ?
Make 10 circles around the stadium
!
Above mentioned expressions are used
every day, and nobody is used to
say:
Keep making loops with your
legs.
Could you loop what you just said
?
Loop around the stadium 10 times
!
Although it sounds funny, at the same
time it's true - moving one leg in
front of another repeatedly is a loop,
just as circulating around the
stadium. Engines use loops too:
Millions of people work on factory
lines, having loops as their work
basics:
And in all these cases there's no help
- actions must be repeated manually,
sometimes with help from automatized
machines. And talking about machines,
did computers borrow this process too
? Yep, they did ! Programmers had
enough of hard manual work, repeating
the same routines again and again...
so they added looping !
Loops & MMB
That's how it's done in MMB ! Pour
commands, just like syrup, until you
have enough !
To use loops, you'll start by writing
a For clause:
For
...adding a numerical variable that
will be used as a counter:
Counter
...followed by equal sign:
=
...then writing starting value for a
range of Counter variable
:
1
...and adding To clause:
To
After this, you'll write an ending
value of range for Counter
variable:
100
Let's see now how the first
for..next loop line looks
like:
For Counter=1 To 100
Line above tells MMB that everything
written below should be repeated. And
how many times ? From the starting
value of numerical variable, to an
ending value of that variable.
After setting loop properties with
code line above, you can start writing
code lines that will be performed in
the loop. In code sample above,
commands would be executed 100 times
(as specified through Counter
numerical variable). So, let's write
some already-known commands:
var$='Hello from loop, this is first
message box'
Message("","var$")
var$='Hello from loop, this is second
message box'
Message("","var$")
These lines will display two message
boxes. One saying Hello from loop,
this is first message box, and the
second one saying Hello from loop,
this is second message box . If
these lines were executed without
loop, message boxes would appear only
once each. But ! Specifying loop using
For Counter=1 To 100, we said
to MMB: repeat showing these
message boxes hundred times each !
Every var$ would be assigned 100
times. Every message box would appear
100 times.
Once you're done writing commands that
should be executed in loop, it's
necessary to mark the end of such code
block, otherwise MMB wouldn't know
what's inside and outside of the
for..next loop. And running entire
program in one big loop surely ain't
something you want.
Marking the end of for..next loop code
block is done using Next
clause. Remember that numerical
variable Counter, used for
setting number of loop repeats ?
You'll write label of that variable
behind the Next clause:
Next Counter
It's like saying to MMB: once
you're done performing lines in
for..next block, update value of
numerical variable used as a
counter (it goes either +1 or -1,
more about it below) and start
performing block lines all over again
!
Here's colorized summary of for..next
loop code lines:
For
Counter=
1
To
100
var$='Hello from
loop, this is first message box'
Message("","var$")
var$='Hello from loop, this is second
message box'
Message("","var$")
Next
Counter
Loop clauses
For, To,
Next are marked
blue.
Numerical variable that serves as a
loop counter is labeled
Counter
and is marked red.
Range for loop counter is marked
green, in this case
0 -
100.
All code lines that are executed
repeatedly in loop are pink -
var$,
Message("","")
Loop counter
If you stand by the road and count
cars passing by, you'll start from the
first car and think of number "1" .
When another car passes by, you'll add
1 to previous number and keep waiting
for the next car. Until you get bored
and say: Hey, I had enough of this
loop !
Another case is a stopwatch in one
hand, a gun in another hand and dozen
of racers on track at some big
stadium. You count down
numbers...
10...9...8...7...6...5...4...3...2...1...BANG
!
Both cases are being used in MMB
for..next loops for counting purposes.
Already mentioned next clause
does exactly what people do when
counting things - it either adds 1 or
substracts 1 to/from some number
(represented as numerical variable).
That way, MMB's numerical variable
"remembers" number of repeats it
performed on code block inside loop
and once it reaches ending value of
range - loop is over, and BANG is
heard (just kidding).
Sample above uses numerical variable
i as a counter. Loop code block
is performed 5 times, and after that,
MMB continues executing code lines
below For..Next loop block. It means
that message box saying "After-loop
message! !" will not be displayed
before loop block is performed
n times (in this case -
5).
Counting cases above mention both
positive (+1) and negative (-1)
counting. Examples of positive
counting have been used before, but
here's another one:
For Love=1 To 10
var$='I love MMB'
Message("","var$")
Next Love
That's when you start with lower value
(Love=1) and end with higher
value (To 10).
Counting in opposite (negative, -1)
direction can also be used:
For Seconds=10 To 1
var$='Woof !'
Message("","var$")
Next Seconds
Here you start with higher value
(Seconds=10) and end with lower
value (to 1).
MMB compares starting and ending
value, automatically deciding in what
direction should it go. Of course,
it's not necessary to use
number 1 as either starting or ending
point:
For MileAge=90 To 100
var$='Almost there!'
Message("","var$")
Next MileAge
This example uses 90 as a loop
starting value and 100 as an ending
value. So how many times will loop
code be repeated ? Yep ! 10
!
And it's not like you'll just use
for..next loop to execute fixed code !
While MMB uses numerical variables for
counters, and numerical variables can
be used wherever you want in your
code, current value of loop counter
can be used for some dynamic
actions.
It's like walking from one runner to
another before the race, giving 'em
t-shirt labels saying "You're number
1", "You're number 2", "You're number
23473"...
Let's take a look at loop code
sample:
For Runner=1 To 10
var$='You are runner no.
'+CHAR(Runner)
Message("","var$")
Next Runner
Loop above uses numerical variable
Runner to execute some code
lines 10 times.
Assigning of text to string variable
var$ is interesting - it first
sets text "You are runner no." and
then uses CHAR function to convert
current value of numerical variable
Runner (used as a loop counter,
remember ?) to act as a string, when
+ operator assigns it to
var$ .
The result ? Loop will show message
box 10 times, but contents will be
adjusted according to current value of
loop counter. So, message box will
every time read different numerical
value:
You are runner no. 1
You are runner no. 2
You are runner no.
3
You are runner no. 4
You are runner no. 5
You are runner no. 6
You are runner no. 7
You are runner no. 8
You are runner no. 9
You are runner no. 10
This ability is very useful for
intensive processing of items, names,
records, files... you only change
index number and everything else goes
through the same block of commands
inside the loop. A true time saver -
imagine writing & maintaining the
same block of commands for every item
you want to process ! When you get
into using loops, you will never throw
'em away ;)
TIP!
There is also an option to dynamically change the To
ending value from within the For..Next loop counter.
Thanks to this you can prematurely terminate the For..Next
loop in a certain conditions and without the need to
call Return()
or Break() function.
EXAMPLE OF USAGE: The below script script is useless,
but it can show you how to dynamically change the To
value in For...Next loop. Initially, the loop
should be repeated 5 times, but after the third loop,
the loop range is changed to 3 and therefore the For..Next
is terminated.
**This loop is terminated
after 3 loops... maxloop=5 For i=1 To maxloop Message("in
loop","") If (i=3) Then
** maxloop is now 3!! maxloop=i End Next
i Message("outside loop","")
Loop utilities
Once in a while it's possible to have
a need for an endless loop that will,
for example, check some things (system
info, file existence, user input...)
occasionally and without specific
number of repeats. That's when
Infinite loops come into
action:
For check=1 To Infinity
check=check+1
DisplayValue("Text","check")
Next check
Code sample above uses Infinity
clause as an ending value of numerical
variable counter, thus making
definition of loop saying "Start with
1 and never stop" . Of course, that
never is hypothetical - loop is
repeated while your program is running
and project page is not changed. If
either user exits program, changes
page or computer shuts program down,
loop will reach the very end of it's
infinity ;)
Issue emerging from using this kind of
loops is - program functioning while
such loop is being performed. Will
everything be blocked while infinity
loop keeps repeating ?
Not really, but to allow other
objects & scripts to work properly
it is recommended to use flow
commands:
Refresh() - gives time to other
threads being used by program to
perform their actions
Pause("") - stops execution of code
block for specified amount of time (in
msecs)
Read more about these in command
descriptions, here's how they work for
loops:
For check=1 To Infinity
check=check+1
DisplayValue("Text","check")
Refresh()
Next check
Put after loop code block,
Refresh() gives time to other
program threads before starting
another repetition of code
block.
For check=1 To Infinity
check=check+1
DisplayValue("Text","check")
Pause("500")
Next check
Put after loop code block,
Pause("500") makes delay (in
this case 500 miliseconds - half a
second) before repeating code block.
It means that loop code will be
executed every half a second. Even
higher delay periods are recommended
for tasks where real-time check-ups
are not of a critical
importance.
Another issue related to infinity
loops in service of check-ups is a
case when some condition has been
fulfilled and loop should be stopped.
In that case Return() command is a
great help, while it stops further
execution of entire script:
For check=1 To Infinity
check=check+1
DisplayValue("Text","check")
If (UserInput$='GO')
Then
Return()
End
Pause("500")
Next check
In case you don't want to stop execution
of entire script, but only jump from the current For..Next
loop, use Break()
command instead. The execution of code will continue
after "Next n" line of
the For..Next loop where the Break() function was used.
Loop above is "smart" enough to
perform repetition as long as value of
string variable UserInput$ doesn't
match fixed value "GO" . When
UserInput$ contains correct value, if
statement will call Return() command
and loop (together with any code lines
below the loop block) will be stopped.
This routine is oftenly being used to
call some other script with RunScript
and ScriptTimer commands:
For check=1 To Infinity
check=check+1
DisplayValue("Text","check")
If (UserInput$='GO')
Then
RunScript("InputCorrect")
Return()
End
Pause("500")
Next check
Read more about RunScript and
ScriptTimer in their command
descriptions.
That's about everything to tell on the
loop subject ! If you're a beginner in
MMB scripting, loops probably won't be
the first subject you'll get into, and
instead you'll use manual code
repetitions. But as you make progress
in MMB scripting learning curve, loops
will come up as a very comfortable
solution for tasks with intensive
scripting.
|